﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;

using System.Text;
using System.Windows.Forms;
using Common;

namespace ImageProcessPlugins
{
    public partial class RotateInputForm : Form
    {
        private Document doc;
        private Bitmap SourceBitmap;
        private Bitmap CurrentBitmap;
        private ImageProcessApp app;

        public void SetCurrentDoc(Document currentDoc)
        {
            doc = currentDoc;
            SourceBitmap = doc.GetBitmap();
        }

        public void SetImageProcessApp(ImageProcessApp imageProcessApp)
        {
            app = imageProcessApp;
        }

        private float GetAngle(float angle)
        {
            if (angle >= 0 && angle < 360) return angle;
            else
            {
                int n = (int)(angle / 360);
                if (n > 0) return angle - 360 * n;
                else return angle + 360 * (n + 1);
            }
        }

        private void Rotate(float rotateAngle, bool preview)
        {
            rotateAngle = GetAngle(rotateAngle);
            double angle = rotateAngle / 180 * Math.PI;
            float dx, dy;
            if (angle <= Math.PI / 2)
            {
                CurrentBitmap = new Bitmap((int)(SourceBitmap.Width * Math.Cos(angle) + SourceBitmap.Height * Math.Sin(angle)), (int)(SourceBitmap.Width * Math.Sin(angle) + SourceBitmap.Height * Math.Cos(angle)));
                dx = SourceBitmap.Height * (float)Math.Sin(angle);
                dy = 0;
            }
            else if (angle > Math.PI / 2 && angle < Math.PI)
            {
                CurrentBitmap = new Bitmap((int)(SourceBitmap.Width * Math.Sin(angle - Math.PI / 2) + SourceBitmap.Height * Math.Cos(angle - Math.PI / 2)), (int)(SourceBitmap.Width * Math.Cos(angle - Math.PI / 2) + SourceBitmap.Height * Math.Sin(angle - Math.PI / 2)));
                dx = SourceBitmap.Width * (float)Math.Sin(angle - Math.PI / 2) + SourceBitmap.Height * (float)Math.Cos(angle - Math.PI / 2);
                dy = SourceBitmap.Height * (float)Math.Sin(angle - Math.PI / 2);
            }
            else if (angle >= Math.PI && angle < 1.5 * Math.PI)
            {
                CurrentBitmap = new Bitmap((int)(SourceBitmap.Width * Math.Cos(angle - Math.PI) + SourceBitmap.Height * Math.Sin(angle - Math.PI)), (int)(SourceBitmap.Width * Math.Sin(angle - Math.PI) + SourceBitmap.Height * Math.Cos(angle - Math.PI)));
                dx = SourceBitmap.Width * (float)Math.Cos(angle - Math.PI);
                dy = SourceBitmap.Width * (float)Math.Sin(angle - Math.PI) + SourceBitmap.Height * (float)Math.Cos(angle - Math.PI);
            }
            else
            {
                CurrentBitmap = new Bitmap((int)(SourceBitmap.Width * Math.Sin(angle - Math.PI * 1.5) + SourceBitmap.Height * Math.Cos(angle - Math.PI * 1.5)), (int)(SourceBitmap.Width * Math.Cos(angle - Math.PI * 1.5) + SourceBitmap.Height * Math.Sin(angle - Math.PI * 1.5)));
                dx = 0;
                dy = SourceBitmap.Width * (float)Math.Cos(angle - 1.5 * Math.PI);
            }
            Graphics g = Graphics.FromImage(CurrentBitmap);
            g.TranslateTransform(dx, dy);
            g.RotateTransform(rotateAngle);
            g.DrawImage(SourceBitmap, 0, 0);
            if (preview)
                doc.SetBitmapPreview(CurrentBitmap);
            else
                doc.SetBitmap(CurrentBitmap);
            app.ImageView.ViewMode = ViewMode.BestFit;
        }

        public RotateInputForm()
        {
            InitializeComponent();
        }

        private void rotateTrackBar_ValueChanged(object sender, EventArgs e)
        {
            rotateTextBox.TextChanged -= new EventHandler(rotateTextBox_TextChanged);
            rotateTextBox.Text = rotateTrackBar.Value.ToString();
            rotateTextBox.TextChanged += new EventHandler(rotateTextBox_TextChanged);
            try
            {
                Rotate(Convert.ToSingle(rotateTextBox.Text), true);
            }
            catch (Exception)
            { }
        }

        private void okButton_Click(object sender, EventArgs e)
        {
            try
            {
                doc.SetBitmapPreview(SourceBitmap);
                float angle = Convert.ToSingle(rotateTextBox.Text);
                if (angle != 0) Rotate(Convert.ToSingle(rotateTextBox.Text), false);
                DialogResult = DialogResult.OK;
            }
            catch
            {
                MessageBox.Show("Please input the angle of the rotation, in degrees.");
                DialogResult = DialogResult.None;
            }
        }

        private void cancelButton_Click(object sender, EventArgs e)
        {
            doc.SetBitmapPreview(SourceBitmap);
            app.ImageView.ViewMode = ViewMode.BestFit;
            DialogResult = DialogResult.Cancel;
        }

        private void rotateTextBox_TextChanged(object sender, EventArgs e)
        {
            try
            {
                float angle = Convert.ToSingle(rotateTextBox.Text);
                if (angle != 0) Rotate(Convert.ToSingle(rotateTextBox.Text),true);
            }
            catch
            {
                doc.SetBitmapPreview(SourceBitmap);
                app.ImageView.ViewMode = ViewMode.BestFit;
            }
        }
    }
}
